﻿using System;
using System.Diagnostics;
using OverStore.Runtime.PersistenceServiceProvider;
using System.Globalization;

namespace OverStore.Runtime.ObjectRepository.ChangesTracker
{
    /// <summary>
    /// Define changes of object using checksum. Cheksum is hash of values of 
    /// set of object properties. 
    /// </summary>
    public sealed class ChecksumChangesTracker<TInstance, TIdentifier> : ChangesTrackerBase<TInstance, TIdentifier, int>
        where TInstance : class
    {
        private readonly string[] _Columns;

        /// <summary>
        /// Initializes a new instance of the <see cref="ChecksumChangesTracker&lt;TInstance, TIdentifier&gt;"/> class.
        /// </summary>
        /// <param name="provider">Object provides access to different services that allows to perform different task regarding persisting instance of specified type.</param>
        /// <param name="columns">The collection of names of values in instance data are used for define changes.</param>
        public ChecksumChangesTracker(IPersistenceServiceProvider provider, string[] columns)
            : base(provider)
        {
            if (columns == null)
                throw new ArgumentNullException("columns");
            _Columns = columns;
        }

        /// <summary>
        /// When overrided in derived classes, returns object state of specified instance.
        /// </summary>
        /// <param name="instance">Instance wich state should be got.</param>
        /// <returns>
        /// Object represents state of <paramref name="instance"/>.
        /// </returns>
        protected override int GetObjectStateCore(TInstance instance)
        {
            Debug.Assert(instance != null, "Get state of null object.");
            try
            {
                return CalculateDumpChecksum(instance, _Columns);
            }
            catch (Exception ex)
            {
                throw new PersistingRuntimeException(
                            String.Format(
                                    CultureInfo.InvariantCulture,
                                    "Changes Tracker Error: getting state of instance of type {0} failed.", 
                                    typeof(TInstance)),
                            ex);
            }
        }
    }
}